//
// RS Game Framework
// Copyright © 2009 Jedd Haberstro
// jhaberstro@gmail.com
// 
// $Id:
//

#include "rs/Portability.hpp"


#ifndef RS_ASSERT_HPP
#define RS_ASSERT_HPP

#ifndef RS_ASSERT_ENABLED
#   if defined(RS_DEBUG) || defined(RS_TEST)
#       define RS_ASSERT_ENABLED
#   endif
#endif

#ifdef RS_ASSERT_ENABLED
#   define RS_ASSERT(condition, message) \
        do { \
            if (!(condition) && rs::Assert::Report(__FILE__, __LINE__, #condition, message)) { \
                RS_EXIT(); \
            } \
        } while(false)
        
#   define RS_ASSERTF(condition, message, ...) \
        do { \
            if (!(condition) && rs::Assert::Reportf(__FILE__, __LINE__, #condition, message, __VA_ARGS__)) { \
                RS_EXIT(); \
            } \
        } while(false)
#else
#   define RS_ASSERT(condition, message) do { RS_UNUSED(condition); RS_UNUSED(message); } while(false)
#   define RS_ASSERTF(condition, message, ...) do { RS_UNUSED(condition); RS_UNUSED(message); } while(false)
#endif

namespace rs
{
    class Assert
    {
    public:
        
        typedef Boolean (*ReportHandler)(Char8 const* file, RsSize line, Char8 const* condition, Char8 const* message);
        
        static Boolean Report(Char8 const* file, RsSize line, Char8 const* condition, Char8 const* message);

        static Boolean Reportf(Char8 const* file, RsSize line, Char8 const* condition, Char8 const* message, ...);
        
        static ReportHandler GetReportHandler();
        
        static void SetReportHandler(ReportHandler handler);
        
    private:
        
        Assert();
        
        Assert(Assert const&);
        
        Assert& operator=(Assert const&);
    };
    
}

#endif // RS_ASSERT_HPP
